// Header Protection
#ifndef _LIST_H_
#define _LIST_H_

// Include Files
#include "Definitions.h"
#include <assert.h>

// Namespace
namespace IE
{
	/////////////////////////////////////////////////////////////////////////////////
	// A list class which contains a variable length array of the templated type. 
	//     The assignment operator is called on each element during copy operations, 
	//     making this class slow, but safe for dynamic memory. If your templated 
	//     type does not contain dynamic memory, you should use the faster 
	//     'flist_t' instead.
	// element_t: template - the type of data to store in each element of the list
	template< typename element_t >
	class list_t
	{
	public:     // accessors
		uint_t GetSize() const { return m_uSize; }

	public:     // methods

		// A constructor which creates an empty list.
		list_t() : m_pData(CE_NULL), m_uSize(0), m_uCapacity(0) { }

		// A constructor which creates a list with the given capacity.
		// _uCapacity: uint_t - the starting capacity of the list
		explicit list_t( uint_t _uCapacity );

		// A constructor which creates a list by copying an array.
		// _pData: element_t * - data which the list will copy
		// _uCount: uint_t     - the amount of data to copy
		list_t( element_t *_pData, uint_t _uCount );

		// A constructor which creates a list as a copy of another list.
		// _rList (list_t const &) - a list to copy
		list_t( list_t const & _rList );

		// Destructor.
		~list_t() { if(m_pData) delete[] m_pData; }

		// Appends an item to the end of the list.
		// _rElement: element_t & - the item to append to the end of the list
		void Append( element_t & _rElement );

		// Set the capacity of the list. If the new capacity is less than the 
		//     current size, the excess elements will be truncated.
		// _uCapacity: uint_t - the new capacity of the list
		void SetCapacity( uint_t _uCapacity );

		// Clears the list.
		void Clear();

	public:     // operators

		// Makes this list a copy of the given list.
		// _rList: list_t const & - the list to copy
		// return: list_t & - this list
		list_t & operator =( list_t const & _rList );

		// Accesses the given element of the list.
		// _iIndex: int_t - the index to access
		// return: element_t & - the data at the given index
		inline element_t & operator []( uint_t _uIndex )
		{
			assert( _uIndex < m_uSize );
			return m_pData[_uIndex];
		}

		inline element_t const & operator []( uint_t _uIndex ) const
		{
			assert( _uIndex < m_uSize );
			return m_pData[_uIndex];
		}

	private:    // data
		element_t * m_pData;
		uint_t      m_uSize;
		uint_t      m_uCapacity;
	};

	/////////////////////////////////////////////////////////////////////////////////
	// An alternative to 'list_t' which uses memcpy for copy operations, making this 
	//     version faster but unsafe if the templated type contains dynamic memory.
	// element_t: template - the type of data to store in each element of the list
	template< typename element_t >
	class flist_t
	{
	public:     // accessors
		uint_t GetSize() const { return m_uSize; }

	public:     // methods

		// A constructor which creates an empty list.
		flist_t() : m_pData(NULL), m_uSize(0), m_uCapacity(0) { }

		// A constructor which creates a list with the given capacity.
		// _uCapacity: uint_t - the starting capacity of the list
		explicit flist_t( uint_t _uCapacity );

		// A constructor which creates a list by copying an array.
		// _pData: element_t * - data which the list will copy
		// _uCount: uint_t     - the amount of data to copy
		flist_t( element_t * _pData, uint_t _uCount );

		// A constructor which creates a list as a copy of another list.
		// _rList (list_t const &) - a list to copy
		flist_t( flist_t const & _rList );

		// Destructor.
		~flist_t() { if(m_pData) delete[] m_pData; }

		// Appends an item to the end of the list.
		// _rElement: element_t & - the item to append to the end of the list
		void Append( element_t & _rElement );

		// Set the capacity of the list. If the new capacity is less than the 
		//     current size, the excess elements will be truncated.
		// _uCapacity: uint_t - the new capacity of the list
		void SetCapacity( uint_t _uCapacity );

		// Clears the list.
		void Clear();

	public:     // operators

		// Makes this list a copy of the given list.
		// _rList: list_t const & - the list to copy
		// return: list_t & - this list
		flist_t & operator =( flist_t const & _rList );

		// Accesses the given element of the list.
		// _uIndex: uint_t - the index to access
		// return: element_t & - the data at the given index
		inline element_t & operator []( uint_t _uIndex )
		{
			assert( _uIndex < m_uSize );
			return m_pData[_uIndex];
		}

		inline element_t const & operator []( uint_t _uIndex ) const
		{
			assert( _uIndex < m_uSize );
			return m_pData[_uIndex];
		}

	private:    // data
		element_t *m_pData;
		uint_t     m_uSize;
		uint_t     m_uCapacity;
	};
}

// Template Implementation
#include "List.hpp"

// Header Protection
#endif // _LIST_H_
